﻿using Abp.Domain.Repositories;
using Camc.Quality.Bop;
using Camc.Quality.DataCenter.ProductTaskBoard;
using Camc.Quality.DataCenter.RocketProjectBoard;
using Camc.Quality.DataDictionary;
using Camc.Quality.ProductionPlan;
using Camc.Quality.Quality;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Camc.Quality.DataCenter.RocketProjectBoard.RocketProjectReportDto;

namespace Camc.Quality.DataCenter
{
    public class RocketProjectBoardAppService : QualityAppServiceBase
    {
        private readonly IRepository<ProductionScheduler, Guid> _productionSchedulerRepository;
        private readonly IRepository<BopDesc, Guid> _bopDescRepository;
        private readonly IRepository<WorkStepEntity, Guid> _workStepEntityRepository;
        private readonly IRepository<TechniqueEntity, Guid> _techniqueEntityRepository;
        private readonly IRepository<BopNode, Guid> _bopNodeRepository;
        private readonly IRepository<ProcessesEntity, Guid> _processesEntityRepository;
        public RocketProjectBoardAppService(IRepository<ProductionScheduler, Guid> productionSchedulerRepository,
                                          IRepository<BopDesc, Guid> bopDescRepository,
                                          IRepository<WorkStepEntity, Guid> workStepEntityRepository,
                                          IRepository<TechniqueEntity, Guid> techniqueEntityRepository,
                                          IRepository<BopNode, Guid> bopNodeRepository,
                                          IRepository<ProcessesEntity, Guid> processesEntityRepository
            )
        {
            _productionSchedulerRepository = productionSchedulerRepository;
            _bopDescRepository = bopDescRepository;
            _workStepEntityRepository = workStepEntityRepository;
            _techniqueEntityRepository = techniqueEntityRepository;
            _bopNodeRepository = bopNodeRepository;
            _processesEntityRepository = processesEntityRepository;
        }
        /// <summary>
        /// 火箭计划看板查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public RocketProjectReportDto GetRocketProjectReportList(Guid? modelId, Guid lotNoId)
        {
            RocketProjectReportDto rocketProjectReportDto = new RocketProjectReportDto();
            RocketProjectReportData rocketReportData = new RocketProjectReportData();
            List<RocketProjectReportList> rocketProjectReportLists = new List<RocketProjectReportList>();
            var bopDesc = _bopDescRepository.FirstOrDefault(s => s.ModelId == modelId && s.LotNoId == lotNoId);
            if (bopDesc != null)
            {
                //List<XJReportListDto> xJReportListDtos = new List<XJReportListDto>();
                var query = (from xjnode in _bopNodeRepository.GetAll().Where(s => s.ParentId == bopDesc.Id)
                             join desc in _bopDescRepository.GetAll()
                             on xjnode.ParentId equals desc.Id
                             select new
                             {
                                 Id = xjnode.Id,
                                 Name = xjnode.NodeName,
                                 NodeCode = xjnode.NodeCode,
                                 DrawingNo = xjnode.NodeDrawingNo
                             }).ToList();
                int u = 0;
                var xJNode = query.OrderBy(ee =>
                {
                    u = Array.IndexOf(new string[]
                    {
                        "芯一级",
                        "芯二级",
                        "芯三级",
                        "星罩",
                        "助推Ⅰ",
                        "助推Ⅱ",
                        "助推Ⅲ",
                        "助推Ⅳ"
                    }, ee.Name);
                    if (u != -1) { return u; }
                    else { return int.MaxValue; }
                });
                foreach (var item in xJNode)
                {
                    RocketProjectReportData rocketProjectReportData = new RocketProjectReportData();
                    List<RocketProjectReportList> bTLists = new List<RocketProjectReportList>();
                    RocketProjectReportList rocketProjectReportList = new RocketProjectReportList();
                    var productionScheduler = _productionSchedulerRepository.FirstOrDefault(s => s.NodeId == item.Id);
                    var btList = _bopNodeRepository.GetAll().Where(s => s.ParentId == item.Id).ToList();
                    rocketProjectReportData.Name = item.Name;
                    rocketProjectReportData.DrawingNo = item.DrawingNo;
                    rocketProjectReportData.Rank = "芯级";
                    if (productionScheduler != null)
                    {
                        rocketProjectReportData.PlanStartTime = productionScheduler.StartTime;
                        rocketProjectReportData.PlanCompleteTime = productionScheduler.EndTime;
                    }
                    if (btList.Count() > 0)
                    {
                        bTLists = GetXjTaskList(btList, bopDesc.Id, bopDesc.WorkingHourStatus);
                        rocketProjectReportList.children = bTLists;
                        //var startDates = rocketProjectReportList.children.Select(d => DateTime.ParseExact(d.data.PlanStartTime.ToString(), "dd.MM.yyyy", null)).ToList();
                        //if (startDates == null || startDates.Count() <= 0)
                        //{
                        //    rocketProjectReportData.PlanStartTime = startDates.Min();
                        //}
                        //var completeDates = rocketProjectReportList.children.Select(d => DateTime.ParseExact(d.data.PlanStartTime.ToString(), "dd.MM.yyyy", null)).ToList();
                        //if (completeDates == null || completeDates.Count() <= 0)
                        //{
                        //    rocketProjectReportData.PlanCompleteTime = completeDates.Min();
                        //}
                        rocketProjectReportData.CompleteCount = rocketProjectReportList.children.Select(d => d.data.CompleteCount).Sum();
                        rocketProjectReportData.TaskCount = rocketProjectReportList.children.Select(d => d.data.TaskCount).Sum();
                        rocketProjectReportData.CompleteHour = rocketProjectReportList.children.Select(d => d.data.CompleteHour).Sum();
                        rocketProjectReportData.TaskHour = rocketProjectReportList.children.Select(d => d.data.TaskHour).Sum();
                        //状态
                        if (rocketProjectReportData.TaskCount == rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                        {
                            rocketProjectReportData.State = "已完成";
                        }
                        if (rocketProjectReportData.TaskCount > rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                        {
                            rocketProjectReportData.State = "生产中";
                        }
                        if (rocketProjectReportData.TaskCount == 0)
                        {
                            rocketProjectReportData.State = "未生产";
                        }
                    }
                    else
                    {
                        rocketProjectReportData.CompleteCount = 0;
                        rocketProjectReportData.TaskCount = 0;
                        rocketProjectReportData.CompleteHour = 0;
                        rocketProjectReportData.TaskHour = 0;
                        rocketProjectReportData.State = "未生产";
                    }
                    if (rocketProjectReportData.TaskCount == 0)
                    {
                        rocketProjectReportData.StepCompletionSchedule = 0;
                    }
                    else
                    {
                        rocketProjectReportData.StepCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteCount * 100 / rocketProjectReportData.TaskCount);
                    }
                    if (rocketProjectReportData.TaskHour == 0)
                    {
                        rocketProjectReportData.HourCompletionSchedule = 0;
                    }
                    else
                    {
                        rocketProjectReportData.HourCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteHour * 100 / rocketProjectReportData.TaskHour);
                    }

                    rocketProjectReportList.data = rocketProjectReportData;
                    rocketProjectReportLists.Add(rocketProjectReportList);
                }
                rocketProjectReportDto.children = rocketProjectReportLists;
                rocketReportData.CompleteCount = rocketProjectReportDto.children.Select(d => d.data.CompleteCount).Sum();
                rocketReportData.TaskCount = rocketProjectReportDto.children.Select(d => d.data.TaskCount).Sum();
                if (rocketReportData.TaskCount == 0)
                {
                    rocketReportData.StepCompletionSchedule = 0;
                }
                else
                {
                    rocketReportData.StepCompletionSchedule = decimal.Round(rocketReportData.CompleteCount * 100 / rocketReportData.TaskCount);
                }
                rocketReportData.CompleteHour = rocketProjectReportDto.children.Select(d => d.data.CompleteHour).Sum();
                rocketReportData.TaskHour = rocketProjectReportDto.children.Select(d => d.data.TaskHour).Sum();
                if (rocketReportData.TaskHour == 0)
                {
                    rocketReportData.HourCompletionSchedule = 0;
                }
                else
                {
                    rocketReportData.HourCompletionSchedule = decimal.Round(rocketReportData.CompleteHour * 100 / rocketReportData.TaskHour);
                }
                rocketProjectReportDto.data = rocketReportData;
                return rocketProjectReportDto;
            }
            else
            {
                rocketReportData.CompleteCount = 0;
                rocketReportData.TaskCount = 0;
                rocketReportData.StepCompletionSchedule = 0;
                rocketReportData.CompleteHour = 0;
                rocketReportData.TaskHour = 0;
                rocketReportData.HourCompletionSchedule = 0;
                rocketProjectReportDto.data = rocketReportData;
                rocketProjectReportDto.children = rocketProjectReportLists;
                return rocketProjectReportDto;
            }
        }

        private List<RocketProjectReportList> GetXjTaskList(List<BopNode> btList, Guid bopDescId, string workingHourStatus)
        {
            List<RocketProjectReportList> bTLists = new List<RocketProjectReportList>();
            foreach (var item in btList)
            {
                List<RocketProjectReportList> rocketProjectReportLists = new List<RocketProjectReportList>();
                RocketProjectReportList rocketProjectReportList = new RocketProjectReportList();
                RocketProjectReportData rocketProjectReportData = new RocketProjectReportData();
                //获取部套下所有工艺规程
                var productionScheduler = _productionSchedulerRepository.FirstOrDefault(s => s.NodeId == item.Id);
                var node = _bopNodeRepository.GetAll().Where(d => d.BopDescId == bopDescId && d.NodeCode.StartsWith(item.NodeCode) && d.TechniqueEntityId != null).ToList();
                if (node.Count > 0)
                {
                    rocketProjectReportLists = GetBTTaskListForBoard(node, workingHourStatus);
                }
                //部套名称
                rocketProjectReportData.Name = item.NodeName;
                rocketProjectReportData.DrawingNo = item.NodeDrawingNo;
                rocketProjectReportData.Rank = "部套";
                if (productionScheduler != null)
                {
                    rocketProjectReportData.PlanStartTime = productionScheduler.StartTime;
                    rocketProjectReportData.PlanCompleteTime = productionScheduler.EndTime;
                }
                rocketProjectReportList.children = rocketProjectReportLists;
                //var startDates = rocketProjectReportList.children.Select(d=> DateTime.ParseExact(d.data.PlanStartTime.ToString(), "dd.MM.yyyy", null)).ToList();
                //if (startDates == null || startDates.Count() <= 0)
                //{
                //    rocketProjectReportData.PlanStartTime = startDates.Min();
                //}
                //var completeDates = rocketProjectReportList.children.Select(d => DateTime.ParseExact(d.data.PlanStartTime.ToString(), "dd.MM.yyyy", null)).ToList();
                //if (completeDates == null || completeDates.Count() <= 0)
                //{
                //    rocketProjectReportData.PlanCompleteTime = completeDates.Min();
                //}
                rocketProjectReportData.CompleteCount = rocketProjectReportList.children.Select(d => d.data.CompleteCount).Sum();
                rocketProjectReportData.TaskCount = rocketProjectReportList.children.Select(d => d.data.TaskCount).Sum();
                if (rocketProjectReportData.TaskCount == 0)
                {
                    rocketProjectReportData.StepCompletionSchedule = 0;
                }
                else
                {
                    rocketProjectReportData.StepCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteCount * 100 / rocketProjectReportData.TaskCount);
                }
                rocketProjectReportData.CompleteHour = rocketProjectReportList.children.Select(d => d.data.CompleteHour).Sum();
                rocketProjectReportData.TaskHour = rocketProjectReportList.children.Select(d => d.data.TaskHour).Sum();
                if (rocketProjectReportData.TaskHour == 0)
                {
                    rocketProjectReportData.HourCompletionSchedule = 0;
                }
                else
                {
                    rocketProjectReportData.HourCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteHour * 100 / rocketProjectReportData.TaskHour);
                }
                //状态
                if (rocketProjectReportData.TaskCount == rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                {
                    rocketProjectReportData.State = "已完成";
                }
                if (rocketProjectReportData.TaskCount > rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                {
                    rocketProjectReportData.State = "生产中";
                }
                if (rocketProjectReportData.TaskCount == 0)
                {
                    rocketProjectReportData.State = "未生产";
                }
                rocketProjectReportList.data = rocketProjectReportData;
                bTLists.Add(rocketProjectReportList);
            }
            //xjData.children = rocketProjectReportLists;
            return bTLists;
        }
        private List<RocketProjectReportList> GetBTTaskListForBoard(List<BopNode> node, string workingHourStatus)
        {
            List<RocketProjectReportList> rocketProjectReportLists = new List<RocketProjectReportList>();
            //RocketProjectReportList btData = new RocketProjectReportList();
            if (workingHourStatus == "0")//工序任务
            {
                foreach (var witem in node)
                {
                    RocketProjectReportData rocketProjectReportData = new RocketProjectReportData();
                    RocketProjectReportList rocketProjectReportList = new RocketProjectReportList();
                    //TechniqueEntityDataList techniqueEntityDataList = new TechniqueEntityDataList();
                    var tech = _techniqueEntityRepository.FirstOrDefault(s => s.Id == witem.TechniqueEntityId);
                    var productionScheduler = _productionSchedulerRepository.FirstOrDefault(s => s.NodeId == witem.Id);
                    var processes = from cc in _processesEntityRepository.GetAll()
                                    where cc.TechniqueEntityId == tech.Id
                                    select new StatisticsHour
                                    {
                                        Id = cc.Id,
                                        Hour = cc.ProcessesWorking,
                                    };
                    if (processes.Count() > 0)
                    {
                        var proFinish = (from cc in processes
                                         join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                         where mm.ProductingStatus == ProductingStatus.已完成
                                         select new StatisticsHour
                                         {
                                             Id = cc.Id,
                                             Hour = cc.Hour,
                                         }).ToList();
                        var finishIds = proFinish.Select(d => d.Id);
                        var processesIds = processes.Select(d => d.Id);
                        var leftIds = processesIds.Except(finishIds).ToArray();

                        for (int t = 0; t < leftIds.Length; t++)
                        {
                            var workList = from cc in _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == leftIds[t])
                                           select new
                                           {
                                               Id = cc.Id,
                                           };
                            var workFinish = from cc in workList
                                             join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                             where mm.ProductingStatus == ProductingStatus.已完成
                                             select cc;
                            var workCount = workList.Count();
                            var workFinishCount = workFinish.Count();
                            if (workCount == workFinishCount)
                            {
                                var tempHour = processes.Where(d => d.Id == leftIds[t]).First().Hour;
                                StatisticsHour hour = new StatisticsHour();
                                hour.Id = leftIds[t];
                                hour.Hour = tempHour;
                                proFinish.Add(hour);
                            }
                        }
                        //完成数量
                        rocketProjectReportData.CompleteCount = proFinish.Count();
                        //任务数量
                        rocketProjectReportData.TaskCount = processes.Count();
                        if (rocketProjectReportData.TaskCount == 0)
                        {
                            rocketProjectReportData.StepCompletionSchedule = 0;
                        }
                        else
                        {
                            rocketProjectReportData.StepCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteCount * 100 / rocketProjectReportData.TaskCount);
                        }
                        //完成工时
                        rocketProjectReportData.CompleteHour = (int)proFinish.Sum(d => d.Hour);
                        //任务工时
                        rocketProjectReportData.TaskHour = (int)processes.Sum(d => d.Hour);
                        if (rocketProjectReportData.TaskHour == 0)
                        {
                            rocketProjectReportData.HourCompletionSchedule = 0;
                        }
                        else
                        {
                            rocketProjectReportData.HourCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteHour * 100 / rocketProjectReportData.TaskHour);
                        }
                    }
                    else
                    {
                        //完成数量
                        rocketProjectReportData.CompleteCount = 0;
                        //任务数量
                        rocketProjectReportData.TaskCount = processes.Count();
                        rocketProjectReportData.StepCompletionSchedule = 0;
                        //完成工时
                        rocketProjectReportData.CompleteHour = 0;
                        //任务工时
                        rocketProjectReportData.TaskHour = (int)processes.Sum(d => d.Hour);
                        rocketProjectReportData.HourCompletionSchedule = 0;
                    }
                    //规程图号
                    rocketProjectReportData.DrawingNo = tech.TechniqueNumber;
                    //规程名称
                    rocketProjectReportData.Name = tech.TechniqueName;
                    rocketProjectReportData.Rank = "工艺规程";
                    //状态
                    if (rocketProjectReportData.TaskCount == rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                    {
                        rocketProjectReportData.State = "已完成";
                    }
                    if (rocketProjectReportData.TaskCount > rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                    {
                        rocketProjectReportData.State = "生产中";
                    }
                    if (rocketProjectReportData.TaskCount == 0)
                    {
                        rocketProjectReportData.State = "未生产";
                    }
                    if (productionScheduler != null)
                    {
                        rocketProjectReportData.PlanStartTime = productionScheduler.StartTime;
                        rocketProjectReportData.PlanCompleteTime = productionScheduler.EndTime;
                    }
                    rocketProjectReportList.data = rocketProjectReportData;
                    rocketProjectReportLists.Add(rocketProjectReportList);
                }
            }
            if (workingHourStatus == "1")//工步任务
            {
                foreach (var witem in node)
                {
                    RocketProjectReportData rocketProjectReportData = new RocketProjectReportData();
                    RocketProjectReportList rocketProjectReportList = new RocketProjectReportList();
                    var tech = _techniqueEntityRepository.FirstOrDefault(s => s.Id == witem.TechniqueEntityId);
                    var productionScheduler = _productionSchedulerRepository.FirstOrDefault(s => s.NodeId == witem.Id);
                    List<StatisticsHour> hours = new List<StatisticsHour>();
                    if (tech != null)
                    {
                        var totalWork = from cc in _workStepEntityRepository.GetAll()
                                        where cc.TechniqueEntityId == tech.Id
                                        select new StatisticsHour { Id = cc.Id, Hour = cc.WorkStepWorking };
                        var workSteps = (from cc in _processesEntityRepository.GetAll()
                                         join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                         join pp in _workStepEntityRepository.GetAll() on cc.Id equals pp.ProcessesEntityId
                                         where ff.ProductingStatus == ProductingStatus.已完成 && cc.TechniqueEntityId == tech.Id
                                         select new StatisticsHour { Id = pp.Id, Hour = pp.WorkStepWorking }).ToList();
                        var workFinish = (from cc in totalWork
                                          join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                          where ff.ProductingStatus == ProductingStatus.已完成
                                          select new StatisticsHour { Id = cc.Id, Hour = cc.Hour }).ToList();
                        if (workSteps.Count > 0)
                        {
                            hours.AddRange(workSteps);
                        }
                        if (workFinish.Count > 0)
                        {
                            hours.AddRange(workFinish);
                        }

                        if (hours.Count() > 0)
                        {
                            //完成数量
                            rocketProjectReportData.CompleteCount = hours.Count;
                            //任务数量
                            rocketProjectReportData.TaskCount = totalWork.Count();
                            if (rocketProjectReportData.TaskCount == 0)
                            {
                                rocketProjectReportData.StepCompletionSchedule = 0;
                            }
                            else
                            {
                                rocketProjectReportData.StepCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteCount * 100 / rocketProjectReportData.TaskCount);
                            }
                            //完成工时
                            rocketProjectReportData.CompleteHour = (int)hours.Sum(d => d.Hour);
                            //任务工时
                            rocketProjectReportData.TaskHour = (int)totalWork.Sum(d => d.Hour);
                            if (rocketProjectReportData.TaskHour == 0)
                            {
                                rocketProjectReportData.HourCompletionSchedule = 0;
                            }
                            else
                            {
                                rocketProjectReportData.HourCompletionSchedule = decimal.Round(rocketProjectReportData.CompleteHour * 100 / rocketProjectReportData.TaskHour);
                            }
                        }
                        else
                        {
                            //完成数量
                            rocketProjectReportData.CompleteCount = 0;
                            //任务数量
                            rocketProjectReportData.TaskCount = totalWork.Count();
                            rocketProjectReportData.StepCompletionSchedule = 0;
                            //完成工时
                            rocketProjectReportData.CompleteHour = 0;
                            //任务工时
                            rocketProjectReportData.TaskHour = (int)totalWork.Sum(d => d.Hour);
                            rocketProjectReportData.HourCompletionSchedule = 0;
                        }
                        //规程图号
                        rocketProjectReportData.DrawingNo = tech.TechniqueNumber;
                        //规程名称
                        rocketProjectReportData.Name = tech.TechniqueName;
                        //状态
                        if (rocketProjectReportData.TaskCount == rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                        {
                            rocketProjectReportData.State = "已完成";
                        }
                        if (rocketProjectReportData.TaskCount > rocketProjectReportData.CompleteCount && rocketProjectReportData.TaskCount > 0)
                        {
                            rocketProjectReportData.State = "生产中";
                        }
                        if (rocketProjectReportData.TaskCount == 0)
                        {
                            rocketProjectReportData.State = "未生产";
                        }
                        if (productionScheduler != null)
                        {
                            rocketProjectReportData.PlanStartTime = productionScheduler.StartTime;
                            rocketProjectReportData.PlanCompleteTime = productionScheduler.EndTime;
                        }
                        rocketProjectReportList.data = rocketProjectReportData;
                        rocketProjectReportLists.Add(rocketProjectReportList);
                    }
                }
            }
            return rocketProjectReportLists;
        }
        private class StatisticsHour
        {
            public Guid Id { get; set; }

            public decimal Hour { get; set; }
        }
    }
}
